UNICEF REPORT

When Hope Fades: The Story of Najir

Author: Anthea Petrillo
Published: April 26, 2025



Report Objective

This report aims to raise awareness about the tragic reality of child deaths caused by diarrhoea in children under the age of five. Although preventable and treatable condition, it remains one of the leading causes of child mortality in many low-income countries, where access to healthcare is limited.

The narrative voice of this report is that of Najir, a 4-year-old child who tells his story: from when he tells his mother he has a stomach ache, to when, despite efforts to find a cure, he sadly does not survive. Although this is a fictional story, it is plausible enough to reflect what happens in countries with low access to diarrhoea care, where the inadequacy of healthcare resources is tied to economic and social inequalities.


Data Sources

The data used in this report comes from the following datasets:

  1. unicef_indicator_1.csv: provides global data on the percentage of children under five with diarrhoea who can access healthcare facilities
  2. unicef_indicator_2.csv: offers global data on the percentage of healthcare facilities with basic water access
  3. unicef_metadata.csv: includes economic and social data
  4. deaths_caused_by_diarrhoea.csv: provides data on diarrhoea-related child mortality categorized by seven regions: North America, South Asia, Middle East and North Africa, Europe and Central Asia, Latin America and Caribbean, East Asia and Pacific, Sub-Saharan Africa. You can download it here.

Please find the Tableau version of this report here.


Najir’s Story

My name is Najir, and I am four years old.

I do not feel well. A sharp pain grips my stomach, and my mother tells me I have diarrhoea. She holds my hand tightly, her face etched with worry, her eyes filled with silent fear. “We must find help,” she says. However, seeking medical care is not a simple task.

I live in one of the nineteen countries where, according to data collected between 2017 and 2023, among all the children under the age of five suffering from diarrhoea, fewer than 40% have access to medical advice or treatment at a healthcare facility or from a trained provider.


Healthcare access for children with diarrhoea in lowest-access countries

Code
import pandas as pd
from plotnine import ggplot, aes, geom_bar, labs, theme_minimal, theme, element_text, scale_fill_gradient, element_rect

df = pd.read_excel("unicef_indicator_1_filtered_firstgraph.xlsx")

df['access to care for diarrhoea'] = df['access to care for diarrhoea'] * 100

bar_chart = (
    ggplot(df, aes(x='country', y='access to care for diarrhoea', fill='access to care for diarrhoea')) 
    + geom_bar(stat='identity', show_legend=False, width=0.35)  
    + scale_fill_gradient(low='#D5006D', high='#FF80AB') 
    + labs(
        x='Country', 
        y='Access to Care for Diarrhoea (%)'
    ) 
    + theme_minimal() 
    + theme(
        figure_size=(8, 5), 
        plot_background=element_rect(fill='#F5FBFF', color='#F5FBFF'),  
        panel_background=element_rect(fill='#F5FBFF', color='#F5FBFF'), 
        panel_grid_major=None, 
        panel_grid_minor=None,
        axis_text_x=element_text(rotation=45, ha='right', size=10, color='#1F407A'),  
        axis_text_y=element_text(size=8, color='#1F407A', weight='bold'),  
        axis_title_x=element_text(size=12, color='#1F407A', weight='bold'),  
        axis_title_y=element_text(size=10, color='#1F407A', weight='bold'),  
        plot_title=element_text(size=0)  
    )
)

bar_chart

A serious public health crisis is evident: limited accessibility and availability of essential healthcare services in specific areas of the world.

Despite being a preventable and treatable condition, diarrhoea remains one of the leading causes of child mortality in countries where healthcare systems are fragile.

According to the 2021 data, diarrhoea accounted for 9% of all deaths in children under 5 - over 1,200 daily, or 440,000 annually.

The following histogram displays the global distribution of child diarrheal mortality in 2021. Each vertical bar represents a specific mortality rate (from 0% to 16%), while its height indicates how many countries fall into that percentage range.

The visualization’s strength lies in its mosaic composition: each bar is divided into colored segments corresponding to different regions, as shown in the provided legend. The structure simultaneously reveals three key insights:

  • Extent of the phenomenon (horizontal position on the scale)
  • Geographical distribution (color-coded bar segments)
  • Regional representation (width of colored segments).

The graph clearly demonstrates how diarrheal impact varies dramatically across regions, with a gradient ranging from minimal percentages in developed areas to alarming rates in critical zones.

Mortality is highest in Sub-Saharan Africa.

Healthcare access for children with diarrhoea (top 10 poorest countries)

Code
# Libraries
import pandas as pd
import plotly.express as px

# Load the dataset
df = pd.read_csv("unicef_indicator_1 (2).csv")

# List of target countries
countries_of_interest = [
    'Burundi', 'Afghanistan', 'Central African Republic', 'Madagascar', 
    'Somalia', 'Congo, the Democratic Republic of the', 'Malawi', 
    'Niger', 'Chad', 'Mozambique'
]

# Filter dataset: only Male/Female and target countries
df_filtered = df[
    (df["sex"].isin(["Female", "Male"])) &
    (df["country"].isin(countries_of_interest))
]

# Calculate yearly averages by sex
df_grouped = df_filtered.groupby(["time_period", "sex"], as_index=False)["obs_value"].mean()

# Create line plot
fig = px.line(
    df_grouped,
    x="time_period",
    y="obs_value",
    color="sex",
    labels={
        "time_period": "<b>Year</b>",
        "obs_value": "<b>Average Value (%)</b>",
        "sex": "<b>Sex</b>"
    },
    color_discrete_map={
        "Female": "#FF69B4",  # Pink
        "Male": "#00BFFF"     # Blue
    }
)

# Style improvements
fig.update_traces(mode="lines+markers", line_width=2.5)
fig.update_layout(
    plot_bgcolor='rgba(245, 245, 245, 0.1)',  # Very light sandstone background
    paper_bgcolor='rgba(245, 245, 245, 0.1)',
    xaxis=dict(
        tickmode="linear",
        title_font=dict(color="#1F407A", size=14),  # Dark blue bold
        tickfont=dict(color="#333333")
    ),
    yaxis=dict(
        range=[0, 100],
        title_font=dict(color="#1F407A", size=14),  # Dark blue bold
        tickfont=dict(color="#333333")
    ),
    legend_title_font=dict(color="#1F407A"),  # Dark blue legend title
    legend_font=dict(color="#333333"),        # Dark text for legend items
    hoverlabel=dict(
        bgcolor="white",
        font_size=12,
        font_family="Arial"
    )
)

fig.show() 

Fortunately, my mother managed to find a healthcare facility and took me there.
However, the percentage of healthcare facilities with access to basic water services is not the same across the world.

The lack of access to basic water services means that healthcare facilities are unable to treat children suffering from diarrhoea.

Health care facilities & water access: country comparison 2021

Code
import pandas as pd
import plotly.express as px
import warnings

warnings.filterwarnings('ignore')

df = pd.read_csv("unicef_indicator_2 (2).csv")

df_2021 = df[
    (df["time_period"] == 2021) &
    (df["unit_of_measure"] == "%")
].copy()  

df_2021["% Water Access"] = df_2021["obs_value"].apply(lambda x: f"{x:.1f}%")

fig = px.choropleth(
    df_2021,
    locations="alpha_3_code",
    color="obs_value",
    hover_name="country",
    hover_data={
        "alpha_3_code": False,
        "obs_value": False,
        "% Water Access": True
    },
    color_continuous_scale="Blues"
)

fig.update_layout(
    coloraxis_colorbar=dict(
        title="<b>Water Access (%)</b>",
        tickformat=".1f",
        title_font=dict(color="#1F407A", size=12),
        tickfont=dict(color="#1F407A")
    ),
    title=None
)

fig.show()

In countries like mine, parents often have large families because they sadly anticipate that some of their children may not survive. This leads to very high birth rates. Since birth rates and life expectancy are inversely related, higher birth rates typically correspond to lower life expectancy at birth.

Demographic patterns (2021): Birth rate & Life expectancy

Code
import pandas as pd
import plotly.express as px

df = pd.read_csv("unicef_metadata_7.csv")

df_2021 = df[df["year"] == 2021]

df_2021 = df_2021.dropna(subset=["Birth rate, crude (per 1,000 people)", "Life expectancy at birth, total (years)"])

fig = px.scatter(
    df_2021,
    x="Birth rate, crude (per 1,000 people)",
    y="Life expectancy at birth, total (years)",
    hover_name="country",
    trendline="ols",
    color_discrete_sequence=["#FF80AB"],
    trendline_color_override="#4B0082",
    labels={
        "Birth rate, crude (per 1,000 people)": "Birth Rate (per 1,000 people)",
        "Life expectancy at birth, total (years)": "Life Expectancy (years)"
    }
)

fig.update_layout(
    plot_bgcolor="#F5FBFF",
    paper_bgcolor="#F5FBFF",
    xaxis_title="<b>Birth Rate (per 1,000 people)</b>",
    yaxis_title="<b>Life Expectancy (years)</b>",
    xaxis=dict(
        title_font=dict(color="#1F407A", size=14), 
        tickfont=dict(color="#333333", size=12)   
    ),
    yaxis=dict(
        title_font=dict(color="#1F407A", size=14), 
        tickfont=dict(color="#333333", size=12) 
    ),
    hoverlabel=dict(
        bgcolor="white",
        font_size=12
    )
)

fig.show()

Birth Rate Trends: High vs Low Rate Countries

Code
import pandas as pd
from plotnine import ggplot, aes, geom_line, labs, theme_minimal, theme, element_text, scale_color_manual

# Carica i dati
df = pd.read_csv("unicef_metadata_7.csv")

# Definisci i gruppi di paesi
high_birth = ["Niger", "Chad", "Somalia", "Central African Republic", "Mali",
              "Congo", "Nigeria", "Uganda", "Mozambique", "Benin"]
low_birth = ["South Korea", "Hong Kong", "Puerto Rico", "Japan", "Andorra", 
             "San Marino", "Italy", "China", "Spain", "Greece"]

# Assegna etichette personalizzate
df["group"] = df["country"].apply(
    lambda x: "Top 10 High Birth Rate Countries" if x in high_birth else (
              "Top 10 Low Birth Rate Countries" if x in low_birth else None)
)

# Filtra solo i gruppi rilevanti
df_grouped = df[df["group"].notna()]

# Elimina righe con valori nulli
df_grouped = df_grouped.dropna(subset=["Birth rate, crude (per 1,000 people)"])

# Calcola la media annuale per ogni gruppo
media_anni = (
    df_grouped
    .groupby(["year", "group"])["Birth rate, crude (per 1,000 people)"]
    .mean()
    .reset_index()
)

# Crea il grafico
grafico = (
    ggplot(media_anni, aes(x="year", y="Birth rate, crude (per 1,000 people)", color="group")) +
    geom_line(size=1.5) +
    scale_color_manual(values={
        "Top 10 High Birth Rate Countries": "#FF69B4",  # rosa
        "Top 10 Low Birth Rate Countries": "#800080"   # viola
    }) +
    labs(
        x="Year",
        y="Average Birth Rate (per 1,000 people)",
        color="Country Group"
    ) +
    theme_minimal() +
    theme(
        axis_title_x=element_text(color="#1F407A", size=12),  # blu scuro
        axis_title_y=element_text(color="#1F407A", size=12),  # blu scuro
        legend_title=element_text(size=11),
        legend_text=element_text(size=10),
        figure_size=(8, 6)  # grafico più stretto
    )
)

grafico

GDP per capita and its effect on birth rate

Code
import pandas as pd
import plotly.express as px

# Carica il dataset
df = pd.read_csv("unicef_metadata_7.csv")

# Filtra i dati per l'anno 2022 e pulisci
df_2022 = df[df["year"] == 2022]
df_cleaned = df_2022.dropna(subset=["GDP per capita (constant 2015 US$)", "Birth rate, crude (per 1,000 people)"])
df_cleaned["Birth rate, crude (per 1,000 people)"] = df_cleaned["Birth rate, crude (per 1,000 people)"].round(1)

# Crea il grafico con le personalizzazioni richieste
fig = px.scatter(
    df_cleaned,
    x="GDP per capita (constant 2015 US$)",
    y="Birth rate, crude (per 1,000 people)",
    labels={
        "GDP per capita (constant 2015 US$)": "<b>GDP per capita (USD)</b>",
        "Birth rate, crude (per 1,000 people)": "<b>Birth rate (per 1,000 people)</b>"
    },
    color_discrete_sequence=["#FDB79A"],  # Colore rosa per i punti
    trendline="lowess",
    trendline_color_override="#FF69B4"  # Linea viola
)

# Personalizzazione avanzata
fig.update_traces(
    mode='markers',
    marker=dict(
        size=8,
        opacity=0.7,
        line=dict(width=1, color='DarkSlateGrey')
    ),
    selector=dict(mode='markers')
)

# Migliora l'aspetto della linea di tendenza
fig.update_traces(
    line=dict(width=4),
    selector=dict(type='scatter', mode='lines')
)

# Aggiorna il layout con le nuove specifiche
fig.update_layout(
    plot_bgcolor='#F5FBFF',  # Colore sfondo personalizzato
    paper_bgcolor='#F5FBFF',  # Colore area grafico
    xaxis_title="<b>GDP per capita (USD)</b>",
    yaxis_title="<b>Birth rate (per 1,000 people)</b>",
    template="plotly_white",
    font=dict(
        family="Arial",
        size=12,
    ),
    hovermode="closest",
    showlegend=False,
    xaxis=dict(
        range=[0, 100000],
        tickvals=[0, 20000, 40000, 60000, 80000, 100000],
        tickformat=",",
        title_font=dict(color="#1F407A", size=14),  # Asse X blu scuro e grassetto
        tickfont=dict(color="#333333")
    ),
    yaxis=dict(
        range=[0, 45],
        tickvals=[0, 5, 10, 15, 20, 25, 30, 35, 40, 45],
        title_font=dict(color="#1F407A", size=14),  # Asse Y blu scuro e grassetto
        tickfont=dict(color="#333333")
    )
)

# Aggiungi annotazione fonte dati
fig.add_annotation(
    x=0.5,
    y=-0.15,
    xref="paper",
    yref="paper",
    text="Fonte: Dati UNICEF 2022",
    showarrow=False,
    font=dict(
        size=10,
        color="grey"
    )
)

fig.show()
Code
import pandas as pd

# Carica il file
df = pd.read_csv('unicef_metadata_7.csv')

# Assicurati che il GDP per capita sia numerico
df['GDP per capita (constant 2015 US$)'] = pd.to_numeric(df['GDP per capita (constant 2015 US$)'], errors='coerce')

# Filtra solo l'anno 2022
df_2022 = df[df['year'] == 2022]

# Elimina i valori mancanti di GDP per capita
df_2022 = df_2022.dropna(subset=['GDP per capita (constant 2015 US$)'])

# Trova i 10 paesi con GDP per capita più alto
top10_highest_countries = df_2022.sort_values(by='GDP per capita (constant 2015 US$)', ascending=False).head(10)['country'].tolist()

# Trova i 10 paesi con GDP per capita più basso
top10_lowest_countries = df_2022.sort_values(by='GDP per capita (constant 2015 US$)', ascending=True).head(10)['country'].tolist()

# Stampa solo le liste dei paesi
print("TOP 10 paesi con GDP per capita più ALTO nel 2022:")
print(top10_highest_countries)

print("\nTOP 10 paesi con GDP per capita più BASSO nel 2022:")
print(top10_lowest_countries)
TOP 10 paesi con GDP per capita più ALTO nel 2022:
['Monaco', 'Bermuda', 'Luxembourg', 'Ireland', 'Switzerland', 'Cayman Islands', 'Norway', 'Singapore', 'United States', 'Qatar']

TOP 10 paesi con GDP per capita più BASSO nel 2022:
['Burundi', 'Afghanistan', 'Central African Republic', 'Madagascar', 'Somalia', 'Congo, the Democratic Republic of the', 'Malawi', 'Niger', 'Chad', 'Mozambique']

Saving children from preventable deaths like diarrhoea requires better healthcare access and hygiene in vulnerable communities. Your UNICEF donation can save lives and keep hope alive for those still fighting.

Donate